package com.fingard.dsp.bank.directbank.cscb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.util.*;

import static com.fingard.text.StringHelper.trimEndFileSp;

/**
 * 长沙银行-批量支付
 * TODO 银行返回的结果明细中没有对应的批内流水号，无法关联批内的交易，暂时无法获取到批内每一笔的最终交易结果，
 * TODO 客户不使用，暂时不测--20200528
 * @author alan
 * @date 2020-05-18
 * @version 1.0
 */
public class CSCB01BatPayRec extends CSCB01Base implements IBatPayRec {
    /**
     * 批量代付/代发提交
     * @param p_req1988
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        XmlTextWriter xmlWriter = new XmlTextWriter();//发送给银行的报文
        try {
            //0、校验是否为代发工资或者费用报销
            if(!p_req1988.useType.contains("代发工资") && !p_req1988.useType.contains("费用报销")){
                retAts.respCode = "-1";
                retAts.respInfo = "目前系统仅支持代发工资或费用报销，其他类型暂不支持。请在用途中设置为代发工资或费用报销！";
                retAts.writeRetToATS();
                return retAts;
            }
            //1、拼接批量代发内容
            StringBuilder msgXml = new StringBuilder();
            msgXml.append("ACNO|CUR_CODE|ACNAME|CARDFLAG|AMT|POSTSCRIPT|\n");
            while (p_req1988.readRecord()) {
                msgXml.append(p_req1988.readedDetail.recAct).append(separator);//收款账号
                msgXml.append(convertCurToBank(p_req1988.readedDetail.recCur)).append(separator);//收款币种
                msgXml.append(p_req1988.readedDetail.recName).append(separator);//收款户名
                msgXml.append("1".equals(p_req1988.readedDetail.cardType)?"1":"0").append(separator);//卡折标志 0卡1折
                msgXml.append(p_req1988.readedDetail.payAmount).append(separator);//金额
                msgXml.append(p_req1988.readedDetail.askNumber).append(separator);//附言
                msgXml.append("\n");
            }
            WriteBankLogLn("批量代发内容："+msgXml);
            //2、生成批量代发文件
            String fileName=p_req1988.reqBatchNO+"_"+Format.Date8Format.format(p_req1988.getPayDateTime()) + ".dat";
            String remotePath = trimEndFileSp(bankFront.bkTransFolder) + "/";
            String batchFilePath=remotePath+fileName;
            WriteBankLogLn("写入文件路径：" + batchFilePath);
            //-1异常 0成功 1已存在
            int result=-1;
            //dsp与前置机不在同一服务器，需要设置共享目录
            if(bankFront.bkTransFolder.contains("smb:")){
                StringBuilder p_sb = new StringBuilder();
                result=SmbFileUtil.smbWriteFile(remotePath,fileName,msgXml.toString(),p_sb,getCharset());
            }else {
                if(!FileHelper.existFile(batchFilePath)){
                    FileHelper.writeFile(batchFilePath,msgXml.toString(),getCharset());
                    if(FileHelper.existFile(batchFilePath)){
                        result=0;
                    }
                }else {
                    result=1;
                }
            }
            //3、发送请求到银行
            if(result == 0){
                //赋值通用参数
                CSCB01Header bankHeader = new CSCB01Header();
                bankHeader.trCode = "300002";
                bankHeader.reqNo = p_req1988.reqHeader.transSeqID;
                bankHeader.fileFlag = "1";//文件标识 0-报文 1-文件
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("body");
                xmlWriter.writeElementString("batch_no", p_req1988.reqBatchNO, true);
                xmlWriter.writeElementString("pay_acno", p_req1988.ownAct, true);//付款账号
                xmlWriter.writeElementString("pay_acname", p_req1988.ownActName, true);
                xmlWriter.writeElementString("pay_cur_code", convertCurToBank(p_req1988.ownCur));
                xmlWriter.writeElementString("as_flag", "0", true);//是否使用账簿号 0：不需要 1：需要
                xmlWriter.writeElementString("as_acno", "", true);//
                String transType = "";
                if(p_req1988.useType.contains("代发工资")){
                    transType="0001";
                }else if(p_req1988.useType.contains("费用报销")){
                    transType="0002";
                }
                xmlWriter.writeElementString("supply_item", transType, true);//项目编号 0001 代发工资 0002 费用报销
                xmlWriter.writeElementString("amt", p_req1988.totalAmt, true);//总金额
                xmlWriter.writeElementString("count", p_req1988.totalNum, true);//总笔数
                xmlWriter.writeElementString("purpose", p_req1988.useType, true);//用途
                xmlWriter.writeElementString("postscript", p_req1988.memo, true);//附言
                xmlWriter.writeElementString("file_name", fileName, true);//提交的文件名
                xmlWriter.writeEndElement();
                xmlWriter.writeEndDocument();
                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), p_req1988.reqHeader.transType, p_req1988.reqHeader.commandCode);// 发送银行
                //4、处理银行响应报文
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    // 解析银行返回
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        //String tmpRespCode = tmpBkReader.getFirstText("/ap/head/ret_code");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/head/ret_info");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/head/ext_info");
                        String tmpsuccFlag = tmpBkReader.getFirstText("/ap/head/succ_flag");
                        retAts.respCode = "0";
                        retAts.respInfo = StringHelper.joinNotEmpty("+", tmpRetInfo, tmpRetRxtInfo);
                        retAts.reqSeqID = p_req1988.reqBatchNO;
                        if(!"0".equals(tmpsuccFlag) && !"1".equals(tmpsuccFlag) && !"8".equals(tmpsuccFlag)){
                            tmpsuccFlag="other";
                        }
                        retAts.transState = tmpsuccFlag;
                        retAts.payInfoCode = retAts.transState;
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            }else if (result == 1) {
                retAts.respCode = "-1";
                retAts.respInfo = "批次号"+p_req1988.reqBatchNO+"交易日期"+p_req1988.payDate+"已存在";
                retAts.writeRetToATS();
                return retAts;
            } else if (result == -1) {
                retAts.respCode = "-1";
                retAts.respInfo = "批次号"+p_req1988.reqBatchNO+"交易日期"+p_req1988.payDate+"推送代发文件失败";
                retAts.writeRetToATS();
                return retAts;
            }
        } catch (Exception e) {
            WriteBankLogLn("生成批付文件失败，返回异常信息：" + e.getMessage());
            retAts.respCode = "-1";
            retAts.respInfo = "生成批付文件失败，返回异常信息：" + e.getMessage();
            retAts.writeRetToATS();
            return retAts;
        }
        retAts.writeRetToATS();
        return retAts;
    }


    /**
     * 批量代付/代发结果查询
     *
     * @param p_req1998
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //拼接请求报文
            CSCB01Header bankHeader = new CSCB01Header();
            bankHeader.trCode = "200201";
            bankHeader.reqNo = p_req1998.reqHeader.transSeqID;
            bankHeader.fileFlag = "0";//文件标识 0-报文 1-文件
            writeCommonHeader(xmlWriter, bankHeader);
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("batch_no", p_req1998.reqBatchNO));//批次号
            tmpXElement.addChild(new XElement("serial_no", ""));
            tmpXElement.addChild(new XElement("cms_corp_no", ""));
            tmpXElement.addChild(new XElement("tr_acdt", Format.Date8Format.format(p_req1998.getBgnDateTime())));//交易日期
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();
            //发送请求并接收响应
            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString(), p_req1998.reqHeader.transType, p_req1998.reqHeader.commandCode);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/ap/head/ret_code");
                    String returnMsg = tmpBkReader.getFirstText("/ap/head/ret_info");
                    String succ_flag = tmpBkReader.getFirstText("/ap/head/succ_flag");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/head/ext_info");
                    if ("0000".equals(returnCode) && "0".equals(succ_flag)) {
                        int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstTextNotNull("/ap/body/record_num"));
                        int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstTextNotNull("/ap/body/field_num"));
                        if (tmpRecordNum > 0) {
                            String tmpDataMFS = "";
                            String tmpFileFlag = tmpBkReader.getFirstText("/ap/head/file_flag");
                            if ("1".equals(tmpFileFlag)) {
                                String tmpBatchFileName = tmpBkReader.getFirstText("/ap/body/file_name");
                                if(StringHelper.hasAnyChar(bankFront.bkTransFolder)){
                                    String downloadFilePath = trimEndFileSp(bankFront.bkTransFolder) + File.separator;//文件存放路径
                                    //dsp与前置机不在同一服务器，需要设置共享目录
                                    if(bankFront.bkTransFolder.contains("smb:")){
                                        StringBuilder p_sb = new StringBuilder();
                                        tmpDataMFS=SmbFileUtil.smbReadFileText(downloadFilePath,tmpBatchFileName,p_sb,getCharset());
                                    }else {
                                        tmpDataMFS = FileHelper.readFileText(downloadFilePath+tmpBatchFileName, getCharset());
                                    }
                                }else {
                                    retAts.respCode="-1";
                                    retAts.respInfo="BankFront.xml的"+p_req1998.reqHeader.bankCode+"未配置bkTransFolder节点";
                                    retAts.writeAfterDetail();
                                    return retAts;
                                }
                            } else {
                                tmpDataMFS = tmpBkReader.getFirstText("/ap/body/serial_record");
                            }
                            if (StringHelper.hasAnyChar(tmpDataMFS)) {
                                WriteBankLogLn("获取批量代发交易结果为：\n"+tmpDataMFS);
                                StringBuilder tmpSbLog = new StringBuilder();
                                ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(tmpDataMFS, "|", tmpFieldNum, tmpRecordNum + 1, tmpSbLog);
                                if (tmpSbLog.length() == 0) {
                                    retAts.respCode = "0";
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.writeBeforeDetail();
                                    //0交易序号|1账号|2币种|3账户名|4卡折标识|5金额|6摘要|7交易日期|8交易时间|9状态|10错误信息|11批次号|
                                    for (int i = 1; i < tmpArrayList.size(); i++) {
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        String[] tmpEachArr = tmpArrayList.get(i);
                                        tmpRetDetail.payAct = p_req1998.ownAct;
                                        tmpRetDetail.payName = "";
                                        tmpRetDetail.recName = tmpEachArr[3].trim();
                                        tmpRetDetail.recAct =tmpEachArr[1].trim();
                                        tmpRetDetail.payAmount = tmpEachArr[5].trim();
                                        tmpRetDetail.curType = convertCurToATS(tmpEachArr[2].trim());
                                        tmpRetDetail.result = tmpEachArr[9].trim();
                                        tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                        tmpRetDetail.postScript = tmpEachArr[6].trim();//批内流水号
                                        tmpRetDetail.usage =tmpEachArr[6].trim();
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                } else {
                                    retAts.respCode="-1";
                                    retAts.respInfo=tmpSbLog.toString();
                                }
                            } else {
                                retAts.respCode="-1";
                                retAts.respInfo="返回交易结果为空";
                            }
                        }else {
                            retAts.respCode="-1";
                            retAts.respInfo="返回交易结果为空";
                        }
                    } else if("3303".equals(returnCode) && "3".equals(succ_flag)){
                        retAts.respCode = "0";
                        retAts.respInfo = StringHelper.joinNotEmpty(";", returnMsg, tmpRetRxtInfo);
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState =returnCode+"+"+succ_flag;
                        retAts.payInfoCode=retAts.transState;
                        retAts.writeBeforeDetail();
                    }else {
                        retAts.respCode="-1";
                        retAts.respInfo=StringHelper.joinNotEmpty(";", returnMsg, tmpRetRxtInfo);
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
